﻿Imports System.Linq
Imports System.Data
Imports System.Web
Imports log4net
Imports Equipment.DataAccess

Partial Public Class User
    Private Shared logger As ILog = LogManager.GetLogger(GetType(User))
#Region "Properties"
    Private _db As EquipmentDataContext
    Public Property DBContext As EquipmentDataContext
        Get
            Return _db
        End Get
        Set(ByVal value As EquipmentDataContext)
            _db = value
        End Set
    End Property

    Public ReadOnly Property FullName As String
        Get
            Return Me.FirstName & " " & Me.LastName
        End Get
    End Property

    Private _roleList As List(Of Role)
    Public Property Roles As List(Of Role)
        Get
            If _roleList Is Nothing Then

                _roleList = New List(Of Role)

                For Each roleItem In (From r In Database.Instance.UserRoles Where r.UserID = Me.ID Select r.Role)
                    _roleList.Add(roleItem)
                Next

            End If
            Return _roleList
        End Get
        Set(ByVal value As List(Of Role))
            _roleList = value
        End Set
    End Property

    Private _groupList As List(Of Group)
    Public Property Groups As List(Of Group)
        Get
            If _groupList Is Nothing Then

                _groupList = New List(Of Group)

                For Each roleItem In (From g In Database.Instance.UserGroups Where g.UserID = Me.ID Select g.Group)
                    _groupList.Add(roleItem)
                Next

            End If
            Return _groupList
        End Get
        Set(ByVal value As List(Of Group))
            _groupList = value
        End Set
    End Property

    Private _preferenceList As List(Of Preference)
    Public Property Preferences As List(Of Preference)
        Get
            If _preferenceList Is Nothing Then

                _preferenceList = New List(Of Preference)

                For Each preferenceItem In (From p In Database.Instance.Preferences Where p.UserID = Me.ID)
                    _preferenceList.Add(preferenceItem)
                Next

            End If
            Return _preferenceList
        End Get
        Set(ByVal value As List(Of Preference))
            _preferenceList = value
        End Set
    End Property

#End Region

    Public Shared Function RetrieveAll() As IEnumerable(Of User)
        Dim db As EquipmentDataContext = Database.Instance
        Return db.Users.OrderBy(Function(u) u.FirstName)
    End Function

    Public Shared Function RetrieveAllByStatus(ByVal status As UserStatus) As IEnumerable(Of User)
        Return RetrieveAll(0, 0, status = UserStatus.Active)
    End Function

    Public Shared Function RetrieveAll(ByVal siteID As Integer, ByVal roleID As Integer, ByVal groupID As Integer, ByVal departmentID As Integer) As IEnumerable(Of User)
        Dim db As EquipmentDataContext = Database.Instance
        If groupID > 0 AndAlso departmentID > 0 Then
            Return From u In (RetrieveAll(siteID, roleID)) Where u.ID = departmentID AndAlso u.UserGroups.Select(Function(g) g.GroupID).Contains(groupID) Order By u.FirstName
        ElseIf departmentID > 0 Then
            Return From u In (RetrieveAll(siteID, roleID)) Where u.ID = departmentID Order By u.FirstName
        ElseIf groupID > 0 Then
            Return From u In (RetrieveAll(siteID, roleID)) Where u.UserGroups.Select(Function(g) g.GroupID).Contains(groupID) Order By u.FirstName
        Else
            Return RetrieveAll(siteID, roleID)
        End If
    End Function

    Public Shared Function RetrieveAll(ByVal siteID As Integer, ByVal roleID As Integer) As IQueryable(Of User)
        Dim db As EquipmentDataContext = Database.Instance
        If siteID > 0 AndAlso roleID > 0 Then
            Return From u In Database.Instance.Users Where u.SiteID = siteID AndAlso u.UserRoles.Select(Function(r) r.RoleID).Contains(roleID) Order By u.FirstName
        ElseIf siteID > 0 Then
            Return From u In Database.Instance.Users Where u.SiteID = siteID Order By u.FirstName
        ElseIf roleID > 0 Then
            Return From u In Database.Instance.Users Where u.UserRoles.Select(Function(r) r.RoleID).Contains(roleID) Order By u.FirstName
        Else
            Return RetrieveAll()
        End If
    End Function

    Public Shared Function RetrieveAll(ByVal siteID As Integer, ByVal roleID As Integer, ByVal isActive As Boolean) As IEnumerable(Of User)
        Dim db As EquipmentDataContext = Database.Instance
        If siteID > 0 AndAlso roleID > 0 Then
            Return From u In Database.Instance.Users Where u.SiteID = siteID AndAlso u.IsActive = isActive AndAlso u.UserRoles.Select(Function(r) r.RoleID).Contains(roleID) Order By u.FirstName
        ElseIf siteID > 0 Then
            Return From u In Database.Instance.Users Where u.SiteID = siteID AndAlso u.IsActive = isActive Order By u.FirstName
        ElseIf roleID > 0 Then
            Return From u In Database.Instance.Users Where u.IsActive = isActive AndAlso u.UserRoles.Select(Function(r) r.RoleID).Contains(roleID) Order By u.FirstName
        Else
            Return From u In Database.Instance.Users Where u.IsActive = isActive Order By u.FirstName
        End If
    End Function

    Public Shared Function RetrieveAll(ByVal siteID As Integer, ByVal isActive As Boolean) As IEnumerable(Of User)
        Dim db As EquipmentDataContext = Database.Instance
        If siteID > 0 Then
            Return From u In Database.Instance.Users Where u.SiteID = siteID AndAlso u.IsActive = isActive Order By u.FirstName
        Else
            Return From u In Database.Instance.Users Where u.IsActive = isActive Order By u.FirstName
        End If
    End Function

    Public Shared Function GetByPrimaryKey(ByVal id As Integer) As User
        Dim db As EquipmentDataContext = Database.Instance
        Dim result = From u In db.Users Where u.ID = id
        Dim userEntity As User = result.FirstOrDefault()
        If userEntity IsNot Nothing Then
            userEntity.DBContext = db
        End If
        Return userEntity
    End Function

    Public Shared Function GetByUsername(ByVal username As String) As User
        Dim db As EquipmentDataContext = Database.Instance
        Dim result = From u In db.Users Where u.Username = username
        Dim userEntity As User = result.FirstOrDefault()
        If userEntity IsNot Nothing Then
            userEntity.DBContext = db
        End If
        Return userEntity
    End Function

    Public Shared Function SearchByEmailExcept(ByVal email As String, ByVal id As Integer) As IQueryable(Of User)
        Return From u In Database.Instance.Users Where u.Email = email AndAlso u.ID <> id
    End Function

    Public Shared Function SearchByUsernameExcept(ByVal username As String, ByVal id As Integer) As IQueryable(Of User)
        Return From u In Database.Instance.Users Where u.Username = username AndAlso u.ID <> id
    End Function

    Public Shared Sub Insert(ByVal entity As User)
        Dim db As EquipmentDataContext = Database.Instance
        db.Users.InsertOnSubmit(entity)
        Try
            db.SubmitChanges()
            For Each role In entity.Roles
                Dim newItem = New UserRole()
                newItem.UserID = entity.ID
                newItem.RoleID = role.ID
                db.UserRoles.InsertOnSubmit(newItem)
            Next
            For Each group In entity.Groups
                Dim newItem = New UserGroup()
                newItem.UserID = entity.ID
                newItem.GroupID = group.ID
                db.UserGroups.InsertOnSubmit(newItem)
            Next
            db.SubmitChanges()
        Catch ex As Exception
            logger.Error(ex.Message + ":" + ex.StackTrace)
        End Try
    End Sub

    Public Sub Save()
        Dim _dataBase As EquipmentDataContext = Me.DBContext
        Dim roles = From ur In _dataBase.UserRoles Where ur.UserID = Me.ID Select ur
        Dim groups = From ug In _dataBase.UserGroups Where ug.UserID = Me.ID Select ug

        Try
            ' Roles
            For Each role In roles
                Dim currRole As Role = Me.Roles.SingleOrDefault(Function(r) r.ID = role.RoleID)
                If currRole Is Nothing Then
                    _dataBase.UserRoles.DeleteOnSubmit(role)
                End If
            Next
            For Each role In Me.Roles
                Dim currRole As UserRole = roles.SingleOrDefault(Function(r) r.RoleID = role.ID)
                If currRole Is Nothing Then
                    currRole = New UserRole() With {.RoleID = role.ID, .UserID = Me.ID}
                    _dataBase.UserRoles.InsertOnSubmit(currRole)
                End If
            Next

            ' Groups
            For Each group In groups
                Dim currGroup As Group = Me.Groups.SingleOrDefault(Function(g) g.ID = group.GroupID)
                If currGroup Is Nothing Then
                    _dataBase.UserGroups.DeleteOnSubmit(group)
                End If
            Next
            For Each group In Me.Groups
                Dim currGroup As UserGroup = groups.SingleOrDefault(Function(g) g.GroupID = group.ID)
                If currGroup Is Nothing Then
                    currGroup = New UserGroup() With {.GroupID = group.ID, .UserID = Me.ID}
                    _dataBase.UserGroups.InsertOnSubmit(currGroup)
                End If
            Next

            _dataBase.SubmitChanges()
        Catch ex As Exception
            logger.Error(ex.Message + ":" + ex.StackTrace)
        End Try

    End Sub

    Public Sub SavePreferences()
        Dim _dataBase As EquipmentDataContext = Me.DBContext
        Dim preferences = From up In _dataBase.Preferences Where up.UserID = Me.ID Select up

        Try

            ' Groups
            For Each userPreference In preferences
                Dim currPreference As Preference = Me.Preferences.SingleOrDefault(Function(p) p.ID = userPreference.ID)
                If currPreference Is Nothing Then
                    _dataBase.Preferences.DeleteOnSubmit(userPreference)
                End If
            Next
            For Each userPreference In Me.Preferences
                Dim currPreference As Preference = preferences.SingleOrDefault(Function(p) p.ID = userPreference.ID)
                If currPreference Is Nothing Then
                    userPreference.UserID = Me.ID
                    _dataBase.Preferences.InsertOnSubmit(userPreference)
                End If
            Next

            _dataBase.SubmitChanges()
        Catch ex As Exception
            logger.Error(ex.Message + ":" + ex.StackTrace)
        End Try
    End Sub
End Class
